using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace EuropeEngulfed.NET
{
    class PlayingPieceGraphics
    {
        public const string ASW_IMAGE_KEY = "ASWIMAGE";
        public const string WALLIED_BOMBER_IMAGE_KEY = "WALLIEDBOMBERIMAGE";
        public const string GERMAN_BOMBER_IMAGE_KEY = "GERMANBOMBERIMAGE";
        public const string WALLIED_FIGHTER_IMAGE_KEY = "WALLIEDFIGHTERIMAGE";
        public const string GERMAN_FIGHTER_IMAGE_KEY = "GERMANFIGHTERIMAGE";
        public const string WALLIED_FLAK_IMAGE_KEY = "WALLIEDFLAKIMAGE";
        public const string GERMAN_FLAK_IMAGE_KEY = "GERMANFLAKIMAGE";
        public const string FORTIFICATION_IMAGE_KEY = "FORTIFICATIONIMAGE";
        public const string HEAVYFORTIFICATION_IMAGE_KEY = "HEAVYFORTIFICATIONIMAGE";
        public const string UBOAT_IMAGE_KEY = "UBOATIMAGE";
        public const string V1_IMAGE_KEY = "V1IMAGE";
        public const string V2_IMAGE_KEY = "V2IMAGE";

        public enum InfoTrackMarker
        {
            WAlliedBomberPoints,
            WAlliedFigtherPoints,
            BritishFlak,
            BritASW,
            GermanUBoats,
            GermanUBoats30,
            GermanBomber,
            GermanFighter,
            GermanFlak,
            GermanV1,
            GermanV2,
        }
        //Playing Piece Images
        private const int MULT_BLOCK_BACKING_SIZE = 2;
        public const int BLOCK_BACKING_SIZE = 5;
        public const int GSUStackIncrement = 5;

        private static Bitmap GetBlockImage(Block block)
        {
            switch (block.CountryOwner)
            {
                // Neutrals
                case MapInfo.CountryID.Belgium:
                case MapInfo.CountryID.Denmark:
                case MapInfo.CountryID.Greece:
                case MapInfo.CountryID.Netherlands:
                case MapInfo.CountryID.Norway:
                case MapInfo.CountryID.Poland:
                case MapInfo.CountryID.Portugal:
                case MapInfo.CountryID.Spain:
                case MapInfo.CountryID.Sweden:
                case MapInfo.CountryID.Switzerland:
                case MapInfo.CountryID.Turkey:
                case MapInfo.CountryID.Yugoslavia:
                    {
                        switch (block.getBlockType())
                        {
                            case Block.BlockType.armor:
                                return EEGraphics.Neutral2StepArmor;
                            case Block.BlockType.infantry:
                                if (block.MaxStrength == 2)
                                    return EEGraphics.Neutral2StepInf;
                                else if (block.MaxStrength == 3)
                                    return EEGraphics.Neutral3StepInf;
                                break;
                            case Block.BlockType.cavalry:
                                return EEGraphics.Neutral2StepCavalry;
                        }
                    }
                    break;
                case MapInfo.CountryID.Bulgaria:
                    return EEGraphics.Bulg2StepInf;
                case MapInfo.CountryID.Finland:
                    if (block.MaxStrength == 2)
                        return EEGraphics.Fin2StepInf;
                    else if (block.MaxStrength == 3)
                        return EEGraphics.Fin3StepInf;
                    else if (block.MaxStrength == 4)
                        return EEGraphics.Fin4StepInf;
                    break;
                case MapInfo.CountryID.FreeFrance:
                case MapInfo.CountryID.VichyFrance:
                case MapInfo.CountryID.France:
                    switch(block.getBlockType())
                    {
                        case Block.BlockType.infantry:
                            if (block.MaxStrength == 2)
                                return EEGraphics.French2StepInf;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.French3StepInf;
                            else if (block.MaxStrength == 4)
                                return EEGraphics.French4StepInf;
                            break;
                        case Block.BlockType.armor:
                            if (block.MaxStrength == 2)
                                return EEGraphics.French2StepArmor;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.French3StepArmor;
                            break;
                    }
                    break;
                case MapInfo.CountryID.Germany:
                    {
                        switch(block.getBlockType())
                        {
                            case Block.BlockType.militia:
                                if (block.MaxStrength == 1)
                                    return EEGraphics.German1StepMilitia;
                                else if (block.MaxStrength == 2)
                                    return EEGraphics.German2StepMilitia;
                                break;
                            case Block.BlockType.infantry:
                                if (block.MaxStrength == 2)
                                    return EEGraphics.German2StepInf;
                                else if (block.MaxStrength == 3)
                                    return EEGraphics.German3StepInf;
                                else if (block.MaxStrength == 4)
                                    return EEGraphics.Geman4StepInf;
                                break;
                            case Block.BlockType.cavalry:
                                return EEGraphics.German2StepCavalry;
                            case Block.BlockType.armor:
                                if (block.MaxStrength == 3)
                                    return EEGraphics.German3StepArmor;
                                else if (block.MaxStrength == 4)
                                    return EEGraphics.German4StepArmor;
                                break;
                            case Block.BlockType.airborne:
                                if (block.MaxStrength == 2)
                                    return EEGraphics.German2StepAirBorne;
                                else if (block.MaxStrength == 3)
                                    return EEGraphics.German3StepAirBorne;
                                break;
                            case Block.BlockType.eliteInfantry:
                                return EEGraphics.Geman4StepEliteInf;
                            case Block.BlockType.eliteArmor:
                                if (block.MaxStrength == 3)
                                    return EEGraphics.German3StepEliteArmor;
                                else
                                    return EEGraphics.German4StepEliteArmor;
                        }
                    }
                    break;
                case MapInfo.CountryID.GreatBritain:
                    switch(block.getBlockType())
                    {
                        case Block.BlockType.militia:
                            if (block.MaxStrength == 1)
                                return EEGraphics.British1StepMilitia;
                            else if (block.MaxStrength == 2)
                                return EEGraphics.British2StepMilitia;
                            break;
                        case Block.BlockType.infantry:
                            if (block.MaxStrength == 3)
                                return EEGraphics.British3StepInf;
                            else if (block.MaxStrength == 4)
                                return EEGraphics.British4StepInf;
                            break;
                        case Block.BlockType.armor:
                            if (block.MaxStrength == 3)
                                return EEGraphics.British3StepArmor;
                            else if (block.MaxStrength == 4)
                                return EEGraphics.British4StepArmor;
                            break;
                        case Block.BlockType.airborne:
                            if (block.MaxStrength == 2)
                                return EEGraphics.British2StepAirBorne;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.British3StepAirBorne;
                            break;
                    }
                    break;
                case MapInfo.CountryID.Hungary:
                    if (block.MaxStrength == 2)
                        return EEGraphics.Hung2StepInf;
                    else if (block.MaxStrength == 3)
                        return EEGraphics.Hung3StepInf;
                    break;
                case MapInfo.CountryID.Italy:
                    switch(block.getBlockType())
                    {
                        case Block.BlockType.infantry:
                            if (block.MaxStrength == 2)
                                return EEGraphics.Ita2StepInf;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.Ita3StepInf;
                            break;
                        case Block.BlockType.armor:
                            if (block.MaxStrength == 2)
                                return EEGraphics.Ita2StepArmor;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.Ita3StepArmor;
                            break;
                        case Block.BlockType.airborne:
                            return EEGraphics.Ita2StepAirborne;
                    }
                    break;
                case MapInfo.CountryID.Rumania:
                    switch(block.getBlockType())
                    {
                        case Block.BlockType.infantry:
                            if (block.MaxStrength == 2)
                                return EEGraphics.Rum2StepInf;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.Rum3StepInf;
                            break;
                        case Block.BlockType.armor:
                            return EEGraphics.Rum2StepArmor;
                    }
                    break;
                case MapInfo.CountryID.USA:
                    switch(block.getBlockType())
                    {
                        case Block.BlockType.infantry:
                            if (block.MaxStrength == 3)
                                return EEGraphics.US3StepInf;
                            else if (block.MaxStrength == 4)
                                return EEGraphics.US4StepInf;
                            break;
                        case Block.BlockType.armor:
                            if (block.MaxStrength == 3)
                                return EEGraphics.US3StepArmor;
                            else if (block.MaxStrength == 4)
                                return EEGraphics.US4StepArmor;
                            break;
                        case Block.BlockType.airborne:
                            if (block.MaxStrength == 2)
                                return EEGraphics.US2StepAirBorne;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.US3StepAirBorne;
                            break;
                    }
                    break;
                case MapInfo.CountryID.USSR:
                    switch(block.getBlockType())
                    {
                        case Block.BlockType.infantry:
                            if (block.MaxStrength == 2)
                                return EEGraphics.Soviet2StepInf;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.Soviet3StepInf;
                            else if (block.MaxStrength == 4)
                                return EEGraphics.Soviet4StepInf;
                            break;
                        case Block.BlockType.armor:
                            if (block.MaxStrength == 2)
                                return EEGraphics.Soviet2StepArmor;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.Soviet3StepArmor;
                            else if (block.MaxStrength == 4)
                                return EEGraphics.Soviet4StepArmor;
                            break;
                        case Block.BlockType.cavalry:
                            return EEGraphics.Soviet3StepCavalry;
                        case Block.BlockType.airborne:
                            if (block.MaxStrength == 2)
                                return EEGraphics.Soviet2StepAirBorne;
                            else if (block.MaxStrength == 3)
                                return EEGraphics.Soviet3StepAirBorne;
                            break;
                        case Block.BlockType.eliteInfantry:
                            return EEGraphics.Soviet4StepEliteInf;
                        case Block.BlockType.eliteArmor:
                            return EEGraphics.Soviet4StepEliteArmor;
                    }
                    break;
                default:
                    break;
            }
            throw new Exception("Invalid block type and max strength");
        }

        private static Bitmap GetHiddenBlockImage(Block block)
        {
            switch (block.CountryOwner)
            {
                case MapInfo.CountryID.Belgium:
                case MapInfo.CountryID.Denmark:
                case MapInfo.CountryID.Greece:
                case MapInfo.CountryID.Netherlands:
                case MapInfo.CountryID.Norway:
                case MapInfo.CountryID.Poland:
                case MapInfo.CountryID.Portugal:
                case MapInfo.CountryID.Spain:
                case MapInfo.CountryID.Sweden:
                case MapInfo.CountryID.Switzerland:
                case MapInfo.CountryID.Turkey:
                case MapInfo.CountryID.Yugoslavia:
                    return EEGraphics.NeutralHiddenBlock;
                case MapInfo.CountryID.Finland:
                case MapInfo.CountryID.Bulgaria:
                case MapInfo.CountryID.Hungary:
                case MapInfo.CountryID.Rumania:
                    return EEGraphics.AxisMinorHiddenBlock;
                case MapInfo.CountryID.France:
                case MapInfo.CountryID.FreeFrance:
                case MapInfo.CountryID.VichyFrance:
                    return EEGraphics.FrenchHiddenBlock;
                case MapInfo.CountryID.Germany:
                    if (block.getBlockType() == Block.BlockType.eliteArmor || block.getBlockType() == Block.BlockType.eliteInfantry)
                        return EEGraphics.GermanEliteHiddenBlock;
                    else
                        return EEGraphics.GermanHiddenBlock;
                case MapInfo.CountryID.GreatBritain:
                    return EEGraphics.BritishHiddenBlock;
                case MapInfo.CountryID.Italy:
                    return EEGraphics.ItaHiddenBlock;
                case MapInfo.CountryID.USA:
                    return EEGraphics.USHiddenBlock;
                case MapInfo.CountryID.USSR:
                    if (block.getBlockType() == Block.BlockType.eliteArmor || block.getBlockType() == Block.BlockType.eliteInfantry)
                        return EEGraphics.SovietEliteHiddenBlock;
                    else
                        return EEGraphics.SovietHiddenBlock;
                default:
                    return null;
            }
        }

        private static Bitmap GetBlockBackImage(Block block, bool multBacking)
        {
            switch(block.CountryOwner)
            {
                case MapInfo.CountryID.Belgium:
                case MapInfo.CountryID.Denmark:
                case MapInfo.CountryID.Greece:
                case MapInfo.CountryID.Netherlands:
                case MapInfo.CountryID.Norway:
                case MapInfo.CountryID.Poland:
                case MapInfo.CountryID.Portugal:
                case MapInfo.CountryID.Spain:
                case MapInfo.CountryID.Sweden:
                case MapInfo.CountryID.Switzerland:
                case MapInfo.CountryID.Turkey:
                case MapInfo.CountryID.Yugoslavia:
                    if (multBacking)
                        return EEGraphics.NeutralMultBlockBacking;
                    else
                        return EEGraphics.NeutralBlockBacking;
                case MapInfo.CountryID.Finland:
                case MapInfo.CountryID.Bulgaria:
                case MapInfo.CountryID.Hungary:
                case MapInfo.CountryID.Rumania:
                    if (multBacking)
                        return EEGraphics.AxisMultMinorBlockBacking;
                    else
                        return EEGraphics.AxisMinorBlockBacking;
                case MapInfo.CountryID.FreeFrance:
                case MapInfo.CountryID.VichyFrance:
                case MapInfo.CountryID.France:
                    if (multBacking)
                        return EEGraphics.FrenchMultBlockBacking;
                    else
                        return EEGraphics.FrenchBlockBacking;
                case MapInfo.CountryID.Germany:
                    if(block.getBlockType() == Block.BlockType.eliteArmor || block.getBlockType() == Block.BlockType.eliteInfantry)
                    {
                        if (multBacking)
                            return EEGraphics.GermanMultEliteBlockBacking;
                        else
                            return EEGraphics.GermanEliteBlockBacking;
                    }
                    else
                    {
                    if (multBacking)
                        return EEGraphics.GermanMultBlockBacking;
                    else
                        return EEGraphics.GermanBlockBacking;
                    }
                case MapInfo.CountryID.GreatBritain:
                    if (multBacking)
                        return EEGraphics.BritishMultBlockBacking;
                    else
                        return EEGraphics.BritishBlockBacking;
                case MapInfo.CountryID.Italy:
                    if (multBacking)
                        return EEGraphics.ItaMultBlockBacking;
                    else
                        return EEGraphics.ItaBlockBacking;
                case MapInfo.CountryID.USA:
                    if (multBacking)
                        return EEGraphics.USMultBlockBacking;
                    else
                        return EEGraphics.USBlockBacking;
                case MapInfo.CountryID.USSR:
                    if (block.getBlockType() == Block.BlockType.eliteArmor || block.getBlockType() == Block.BlockType.eliteInfantry)
                    {
                        if (multBacking)
                            return EEGraphics.SovietEliteMultBlockBacking;
                        else
                            return EEGraphics.SovietEliteBlockBacking;
                    }
                    else
                    {
                    if (multBacking)
                        return EEGraphics.SovietMultBlockBacking;
                    else
                        return EEGraphics.SovietBlockBacking;
                    }
                default:
                    return null;
            }
        }

        private static Bitmap GetGSUImage(GroundSupportUnit GSU,bool Dogfight)
        {
            switch(GSU.CountryOwner)
            {
                case MapInfo.CountryID.France:
                    if (Dogfight)
                        return EEGraphics.FrenchGSUDogfight;
                    else
                        return EEGraphics.FrenchGSUGroundSupport;
                case MapInfo.CountryID.Germany:
                    if (Dogfight)
                        return EEGraphics.GermanGSUDogFight;
                    else
                        return EEGraphics.GermanGSUGroundSupport;
                case MapInfo.CountryID.GreatBritain:
                    if (Dogfight)
                        return EEGraphics.BritishGSUDogfight;
                    else
                        return EEGraphics.BritishGSUGroundSupport;
                case MapInfo.CountryID.Italy:
                    if (Dogfight)
                        return EEGraphics.ItaGSU;
                    else
                        return EEGraphics.ItaGSUGroundSupport;
                case MapInfo.CountryID.USA:
                    if (Dogfight)
                        return EEGraphics.USGSUDogfight;
                    else
                        return EEGraphics.USGSUGroundSupport;
                case MapInfo.CountryID.USSR:
                    if (Dogfight)
                        return EEGraphics.SovietGSUDogfight;
                    else
                        return EEGraphics.SovietGSUGroundSupport;
            }
            throw new Exception("Invalid GSU");
        }

        public static void PaintBlockFace(Graphics g, Block block, Rectangle rectToDrawOn, bool hideBlocks)
        {
            Bitmap blockImage;
            if (hideBlocks)
                blockImage = GetHiddenBlockImage(block);
            else
                blockImage = GetBlockImage(block);
            Bitmap blockImageToDraw = (Bitmap)blockImage.Clone();
            uint strengthDifference = block.MaxStrength - block.CurrentStrength;

            switch (strengthDifference)
            {
                case 1:
                    blockImageToDraw.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    break;
                case 2:
                    blockImageToDraw.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    break;
                case 3:
                    blockImageToDraw.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    break;
            }

            g.DrawImage(blockImageToDraw, rectToDrawOn);
            blockImageToDraw.Dispose();
        }

        public static void PaintBlock(Graphics g, Block block, Point ptToDrawAt, int numBlocks, bool hideBlocks)
        {
            Bitmap blockImage;
            if(hideBlocks)
                blockImage = GetHiddenBlockImage(block);
            else
                blockImage = GetBlockImage(block);
            Bitmap blockBackImage = GetBlockBackImage(block, numBlocks > 1);
            Bitmap blockImageToDraw = (Bitmap)blockImage.Clone();
            uint strengthDifference = block.MaxStrength - block.CurrentStrength;
            
            switch(strengthDifference)
            {
                case 1:
                    blockImageToDraw.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    break;
                case 2:
                    blockImageToDraw.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    break;
                case 3:
                    blockImageToDraw.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    break;
            }

            ptToDrawAt.X -= blockImageToDraw.Width / 2;
            ptToDrawAt.Y -= blockImageToDraw.Height / 2;
            g.DrawImage(blockImageToDraw, ptToDrawAt);

            if(block.OutOfSupply)
            {
                Point ptToDrawOOS = new Point(ptToDrawAt.X, ptToDrawAt.Y);
                ptToDrawOOS.Y += (blockImageToDraw.Height - EEGraphics.OutOfSupply.Height);
                if(block.OutOfSupplyState == PlayingPiece.OOSState.OOSMoved)
                    g.DrawImage(EEGraphics.OutOfSupplyMoved, ptToDrawOOS);
                else
                    g.DrawImage(EEGraphics.OutOfSupply, ptToDrawOOS);
            }

            if(numBlocks > 1)
            {
                ptToDrawAt.Y -= MULT_BLOCK_BACKING_SIZE;
                ptToDrawAt.X += 1;
                while (numBlocks > 1)
                {
                    g.DrawImage(blockBackImage, ptToDrawAt);
                    ptToDrawAt.X += 1;
                    ptToDrawAt.Y -= MULT_BLOCK_BACKING_SIZE;
                    numBlocks--;
                }
            }
            else
            {
                ptToDrawAt.Y -= BLOCK_BACKING_SIZE;
                ptToDrawAt.X += 1;
                g.DrawImage(blockBackImage, ptToDrawAt);
            }
            blockImageToDraw.Dispose();
        }

        public static void PaintGSUFace(Graphics g, GroundSupportUnit GSU, Rectangle rectToDrawOn, bool dogfight)
        {
            Bitmap GSUImage = GetGSUImage(GSU, dogfight);
            g.DrawImage(GSUImage, rectToDrawOn);
        }

        public static void PaintGSU(Graphics g, GroundSupportUnit GSU, Point ptToDrawAt, bool dogfight)
        {
            Bitmap GSUImage = GetGSUImage(GSU, dogfight);
            ptToDrawAt.X -= GSUImage.Width / 2;
            ptToDrawAt.Y -= GSUImage.Height / 2;
            g.DrawImage(GSUImage, ptToDrawAt);

            if (GSU.OutOfSupply)
            {
                Point ptToDrawOOS = new Point(ptToDrawAt.X, ptToDrawAt.Y);
                ptToDrawOOS.Y += (GSUImage.Height / 2 - EEGraphics.OutOfSupply.Height / 2);
                if (GSU.OutOfSupplyState == PlayingPiece.OOSState.OOSMoved)
                    g.DrawImage(EEGraphics.OutOfSupplyMoved, ptToDrawOOS);
                else
                    g.DrawImage(EEGraphics.OutOfSupply, ptToDrawOOS);
            }
        }

        public static void PaintGSU(Graphics g, GroundSupportUnit GSU, Point ptToDrawAt)
        {
            PaintGSU(g, GSU, ptToDrawAt, true); 
        }

        public static void PaintPlayingPiece(Graphics g, PlayingPiece playingPiece, Point ptToDrawAt)
        {
            if(playingPiece is GroundSupportUnit)
            {
                PaintGSU(g, (GroundSupportUnit)playingPiece, ptToDrawAt);
            }
            else if(playingPiece is Block)
            {
                PaintBlock(g, (Block)playingPiece, ptToDrawAt, 1, false);
            }
            else if(playingPiece is FleetPoint)
            {
                PaintFleetPoint(g, (FleetPoint)playingPiece, ptToDrawAt);
            }
        }

        public static void PaintFleetPointFace(Graphics g, FleetPoint fleetPoint, Rectangle rectToDrawOn)
        {
            Bitmap fleetImage = null;
            switch (fleetPoint.CountryOwner)
            {
                case MapInfo.CountryID.GreatBritain:
                case MapInfo.CountryID.USA:
                    if (fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.USBritishFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.USBritishFleetPoint;
                    break;
                case MapInfo.CountryID.France:
                    if (fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.FrenchFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.FrenchFleetPoint;
                    break;
                case MapInfo.CountryID.Germany:
                    if (fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.GermanFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.GermanFleetPoint;
                    break;
                case MapInfo.CountryID.Italy:
                    if (fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.ItaFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.ItaFleetPoint;
                    break;
                case MapInfo.CountryID.USSR:
                    if (fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.SovietFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.SovietFleetPoint;
                    break;
                default:
                    throw new Exception("Attempted to draw invalid fleet point");
            }
            if (fleetImage != null)
            {
                g.DrawImage(fleetImage, rectToDrawOn);
            }
        }

        public static void PaintFleetPoint(Graphics g, FleetPoint fleetPoint, Point ptToDrawAt)
        {
            Bitmap fleetImage = null;
            switch(fleetPoint.CountryOwner)
            {
                case MapInfo.CountryID.GreatBritain:
                case MapInfo.CountryID.USA:
                    if(fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.USBritishFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.USBritishFleetPoint;
                    break;
                case MapInfo.CountryID.France:
                    if(fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.FrenchFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.FrenchFleetPoint;
                    break;
                case MapInfo.CountryID.Germany:
                    if(fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.GermanFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.GermanFleetPoint;
                    break;
                case MapInfo.CountryID.Italy:
                    if(fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.ItaFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.ItaFleetPoint;
                    break;
                case MapInfo.CountryID.USSR:
                    if (fleetPoint.WithoutTransport)
                        fleetImage = EEGraphics.SovietFleetPointWOutTrans;
                    else
                        fleetImage = EEGraphics.SovietFleetPoint;
                    break;
                default:
                    throw new Exception("Attempted to draw invalid fleet point");
            }
            if(fleetImage != null)
            {
                ptToDrawAt.X -= fleetImage.Width / 2;
                ptToDrawAt.Y -= fleetImage.Height / 2;
                g.DrawImage(fleetImage, ptToDrawAt);
            }

            if (fleetPoint.OutOfSupply)
            {
                Point ptToDrawOOS = new Point(ptToDrawAt.X, ptToDrawAt.Y);
                ptToDrawOOS.Y += (fleetImage.Height - EEGraphics.OutOfSupply.Height);
                g.DrawImage(EEGraphics.OutOfSupply, ptToDrawOOS);
            }
        }

        public static void PaintInfoTrackMarker(Graphics g, InfoTrackMarker infoTrackMarker, Point ptToDrawAt)
        {
            ptToDrawAt.X -= GetMarkerSize().Width / 2;
            ptToDrawAt.Y -= GetMarkerSize().Height / 2;
            switch(infoTrackMarker)
            {
                case InfoTrackMarker.BritASW:
                    g.DrawImage(EEGraphics.BritishASWLevel, ptToDrawAt);
                    break;
                case InfoTrackMarker.BritishFlak:
                    g.DrawImage(EEGraphics.BritishFlakPoints, ptToDrawAt);
                    break;
                case InfoTrackMarker.GermanBomber:
                    g.DrawImage(EEGraphics.GermanBomberPoints, ptToDrawAt);
                    break;
                case InfoTrackMarker.GermanFighter:
                    g.DrawImage(EEGraphics.GermanFighterPoints, ptToDrawAt);
                    break;
                case InfoTrackMarker.GermanFlak:
                    g.DrawImage(EEGraphics.GermanFlakPoints, ptToDrawAt);
                    break;
                case InfoTrackMarker.GermanUBoats:
                    g.DrawImage(EEGraphics.GermanUBoatPoints, ptToDrawAt);
                    break;
                case InfoTrackMarker.GermanUBoats30:
                    g.DrawImage(EEGraphics.GermanUBoatPoints30, ptToDrawAt);
                    break;
                case InfoTrackMarker.GermanV1:
                    g.DrawImage(EEGraphics.GermanV1Points, ptToDrawAt);
                    break;
                case InfoTrackMarker.GermanV2:
                    g.DrawImage(EEGraphics.GermanV2Points, ptToDrawAt);
                    break;
                case InfoTrackMarker.WAlliedBomberPoints:
                    g.DrawImage(EEGraphics.WesternAlliedBomberPoints, ptToDrawAt);
                    break;
                case InfoTrackMarker.WAlliedFigtherPoints:
                    g.DrawImage(EEGraphics.WesternAlliedFighterPoints, ptToDrawAt);
                    break;
            }
        }

        public static void PaintTurnMarker(Graphics g, Point ptToDrawAt, bool alliedTurn)
        {
            if (alliedTurn)
                g.DrawImage(EEGraphics.AlliedTurnMarker, ptToDrawAt);
            else
                g.DrawImage(EEGraphics.AxisTurnMarker, ptToDrawAt);
        }

        public static void PaintNextFleetAllowed(Graphics g, Point ptToDrawAt, MapInfo.CountryID country)
        {
            switch(country)
            {
                case MapInfo.CountryID.France:
                    g.DrawImage(EEGraphics.FrenchNextFleetAllowed, ptToDrawAt);
                    break;
                case MapInfo.CountryID.Germany:
                    g.DrawImage(EEGraphics.GermanNextFleetAllowed, ptToDrawAt);
                    break;
                case MapInfo.CountryID.GreatBritain:
                    g.DrawImage(EEGraphics.BritishNextFleetAllowed, ptToDrawAt);
                    break;
                case MapInfo.CountryID.Italy:
                    g.DrawImage(EEGraphics.ItaNextFleetAllowed, ptToDrawAt);
                    break;
                case MapInfo.CountryID.USA:
                    g.DrawImage(EEGraphics.USNextFleetAllowed, ptToDrawAt);
                    break;
                case MapInfo.CountryID.USSR:
                    g.DrawImage(EEGraphics.SovietNextFleetAllowed, ptToDrawAt);
                    break;
                default:
                    throw new InvalidOperationException();
            }
        }

        public static void PaintNextASWAllowed(Graphics g, Point ptToDrawAt)
        {
            g.DrawImage(EEGraphics.BritishNextASWAllowed, ptToDrawAt);
        }

        public static void PaintNextFlakAllowed(Graphics g, Point ptToDrawAt, MapInfo.CountryID country)
        {
            switch(country)
            {
                case MapInfo.CountryID.Germany:
                    g.DrawImage(EEGraphics.GermanNextFlakAllowed, ptToDrawAt);
                    break;
                case MapInfo.CountryID.GreatBritain:
                    g.DrawImage(EEGraphics.BritishNextFlakAllowed, ptToDrawAt);
                    break;
                default:
                    throw new InvalidOperationException();
            }
        }

        public static Size GetBuildRestrictionMarkerSize()
        {
            return EEGraphics.BritishNextFleetAllowed.Size;
        }

        public static void PaintControlMarker(Graphics g, MapInfo.CountryID country, Point ptToDrawAt, bool transparent)
        {
            Bitmap controlMarkerToDraw;
            switch(country)
            {
                case MapInfo.CountryID.GreatBritain:
                    if (transparent)
                        controlMarkerToDraw = EEGraphics.TransparentBritishControlMarker;
                    else
                        controlMarkerToDraw = EEGraphics.BritishControlMarker;
                    break;
                case MapInfo.CountryID.USA:
                    if (transparent)
                        controlMarkerToDraw = EEGraphics.TransparentUSControlMarker;
                    else
                        controlMarkerToDraw = EEGraphics.USControlMarker;
                    break;
                case MapInfo.CountryID.Germany:
                    if (transparent)
                        controlMarkerToDraw = EEGraphics.TransparentGermanControlMarker;
                    else
                        controlMarkerToDraw = EEGraphics.GermanControlMarker;
                    break;
                case MapInfo.CountryID.USSR:
                    if (transparent)
                        controlMarkerToDraw = EEGraphics.TransparentSovietControlMarker;
                    else
                        controlMarkerToDraw = EEGraphics.SovietControlMarker;
                    break;
                case MapInfo.CountryID.Italy:
                    if (transparent)
                        controlMarkerToDraw = EEGraphics.TransparentItalyControlMarker;
                    else
                        controlMarkerToDraw = EEGraphics.ItalyControlMarker;
                    break;
                case MapInfo.CountryID.France:
                    if (transparent)
                        controlMarkerToDraw = EEGraphics.TransparentFrenchControlMarker;
                    else
                        controlMarkerToDraw = EEGraphics.FrenchControlMarker;
                    break;
                default:
                    throw new Exception("Invalid control marker requested");
            }

            ptToDrawAt.X -= controlMarkerToDraw.Width / 2;
            ptToDrawAt.Y -= controlMarkerToDraw.Height / 2;
            g.DrawImage(controlMarkerToDraw, ptToDrawAt);
        }

        public static string GetTreeViewImageListKeyForSpecialAction(MapInfo.CountryID country)
        {
            return Enum.GetName(country.GetType(), country) + "SA";
        }

        public static void PaintSpecialActionsFace(Graphics g, MapInfo.CountryID country, Rectangle recToDrawOn)
        {
            Bitmap specialActionToDraw;
            switch (country)
            {
                case MapInfo.CountryID.GreatBritain:
                    specialActionToDraw = EEGraphics.BritishSAs;
                    break;
                case MapInfo.CountryID.USA:
                    specialActionToDraw = EEGraphics.USControlSAs;
                    break;
                case MapInfo.CountryID.Germany:
                    specialActionToDraw = EEGraphics.GermanControlSAs;
                    break;
                case MapInfo.CountryID.USSR:
                    specialActionToDraw = EEGraphics.SovietControlSAs;
                    break;
                case MapInfo.CountryID.Italy:
                    specialActionToDraw = EEGraphics.ItalyControlSAs;
                    break;
                case MapInfo.CountryID.France:
                    specialActionToDraw = EEGraphics.FrenchControlSAs;
                    break;
                default:
                    specialActionToDraw = EEGraphics.NeutralControlSAs;
                    break;
            }

            g.DrawImage(specialActionToDraw, recToDrawOn);
        }

        public static void PaintSpecialActions(Graphics g, MapInfo.CountryID country, Point ptToDrawAt)
        {
            Bitmap specialActionToDraw;
            switch (country)
            {
                case MapInfo.CountryID.GreatBritain:
                    specialActionToDraw = EEGraphics.BritishSAs;
                    break;
                case MapInfo.CountryID.USA:
                    specialActionToDraw = EEGraphics.USControlSAs;
                    break;
                case MapInfo.CountryID.Germany:
                    specialActionToDraw = EEGraphics.GermanControlSAs;
                    break;
                case MapInfo.CountryID.USSR:
                    specialActionToDraw = EEGraphics.SovietControlSAs;
                    break;
                case MapInfo.CountryID.Italy:
                    specialActionToDraw = EEGraphics.ItalyControlSAs;
                    break;
                case MapInfo.CountryID.France:
                    specialActionToDraw = EEGraphics.FrenchControlSAs;
                    break;
                default:
                    specialActionToDraw = EEGraphics.NeutralControlSAs;
                    break;
            }

            ptToDrawAt.X -= specialActionToDraw.Width / 2;
            ptToDrawAt.Y -= specialActionToDraw.Height / 2;
            g.DrawImage(specialActionToDraw, ptToDrawAt);
        }

        public static void PaintTransparentSpecialActions(Graphics g, MapInfo.CountryID country, Point ptToDrawAt)
        {
            Bitmap specialActionToDraw;
            switch (country)
            {
                case MapInfo.CountryID.GreatBritain:
                    specialActionToDraw = EEGraphics.TransparentBritishSAs;
                    break;
                case MapInfo.CountryID.USA:
                    specialActionToDraw = EEGraphics.TransparentUSControlSAs;
                    break;
                case MapInfo.CountryID.Germany:
                    specialActionToDraw = EEGraphics.TransparentGermanControlSAs;
                    break;
                case MapInfo.CountryID.USSR:
                    specialActionToDraw = EEGraphics.TransparentSovietControlSAs;
                    break;
                case MapInfo.CountryID.Italy:
                    specialActionToDraw = EEGraphics.TransparentItalyControlSAs;
                    break;
                case MapInfo.CountryID.France:
                    specialActionToDraw = EEGraphics.TransparentFrenchControlSAs;
                    break;
                default:
                    specialActionToDraw = EEGraphics.TransparentNeutralControlSAs;
                    break;
            }

            ptToDrawAt.X -= specialActionToDraw.Width / 2;
            ptToDrawAt.Y -= specialActionToDraw.Height / 2;
            g.DrawImage(specialActionToDraw, ptToDrawAt);
        }

        public static void PaintMiniTransparentSpecialActions(Graphics g, MapInfo.CountryID country, Point ptToDrawAt)
        {
            Bitmap specialActionToDraw;
            switch (country)
            {
                case MapInfo.CountryID.GreatBritain:
                    specialActionToDraw = EEGraphics.MiniTransparentBritishSAs;
                    break;
                case MapInfo.CountryID.USA:
                    specialActionToDraw = EEGraphics.MiniTransparentUSControlSAs;
                    break;
                case MapInfo.CountryID.Germany:
                    specialActionToDraw = EEGraphics.MiniTransparentGermanControlSAs;
                    break;
                case MapInfo.CountryID.USSR:
                    specialActionToDraw = EEGraphics.MiniTransparentSovietControlSAs;
                    break;
                case MapInfo.CountryID.Italy:
                    specialActionToDraw = EEGraphics.MiniTransparentItalyControlSAs;
                    break;
                case MapInfo.CountryID.France:
                    specialActionToDraw = EEGraphics.MiniTransparentFrenchControlSAs;
                    break;
                default:
                    specialActionToDraw = EEGraphics.MiniTransparentNeutralControlSAs;
                    break;
            }

            ptToDrawAt.X -= specialActionToDraw.Width / 2;
            ptToDrawAt.Y -= specialActionToDraw.Height / 2;
            g.DrawImage(specialActionToDraw, ptToDrawAt);
        }

        public static void PaintWeatherMarker(Graphics g,GameState.Weather weather, Point ptToDrawAt)
        {
            Bitmap weatherMarker;
            switch(weather)
            {
                case GameState.Weather.Clear:
                    weatherMarker = EEGraphics.ClearWeatherMarker;
                    break;
                case GameState.Weather.LightMud:
                    weatherMarker = EEGraphics.LtMudWeatherMarker;
                    break;
                case GameState.Weather.Mud:
                    weatherMarker = EEGraphics.MudWeatherMarker;
                    break;
                case GameState.Weather.Snow:
                    weatherMarker = EEGraphics.SnowWeatherMarker;
                    break;
                default:
                    return;
            }

            ptToDrawAt.X -= weatherMarker.Width / 2;
            ptToDrawAt.Y -= weatherMarker.Height / 2;
            g.DrawImage(weatherMarker, ptToDrawAt);
        }

        public static Bitmap GetWesternAlliedFighterImage()
        {
            return EEGraphics.WesternAlliedFighterPoints;
        }

        public static Bitmap GetWesternAlliedBomberImage()
        {
            return EEGraphics.WesternAlliedBomberPoints;
        }

        public static Bitmap GetWesternAlliedFlakImage()
        {
            return EEGraphics.BritishFlakPoints;
        }

        public static Bitmap GetGermanFighterImage()
        {
            return EEGraphics.GermanFighterPoints;
        }

        public static Bitmap GetGermanBomberImage()
        {
            return EEGraphics.GermanBomberPoints;
        }

        public static Bitmap GetGermanFlakImage()
        {
            return EEGraphics.GermanFlakPoints;
        }

        public static Bitmap GetTurnWeatherImage(MapInfo.gameDateWeatherType weatherType)
        {
            Bitmap bitmapToReturn = null;

            switch (weatherType)
            {
                case MapInfo.gameDateWeatherType.clearWeatherAll:
                    bitmapToReturn = EEGraphics.ClearAllWeather;
                    break;
                case MapInfo.gameDateWeatherType.clearWestSouthLtMudEast:
                    bitmapToReturn = EEGraphics.ClearWestSouthLtMudEastWeather;
                    break;
                case MapInfo.gameDateWeatherType.snowEastWestLtMudSouth:
                    bitmapToReturn = EEGraphics.SnowEastWestLtMudSouthWeather;
                    break;
                case MapInfo.gameDateWeatherType.variableWeather:
                    bitmapToReturn = EEGraphics.VariableWeather;
                    break;
            }

            return bitmapToReturn;
        }

        public static void PaintFieldFortification(Graphics g, Rectangle recToDrawOn)
        {
            g.DrawImage(EEGraphics.fieldFortification, recToDrawOn);
        }

        public static void PaintFieldFortification(Graphics g, Point ptToDrawAt)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= EEGraphics.fieldFortification.Width / 2;
            actualPointToDrawAt.Y -= EEGraphics.fieldFortification.Height / 2;

            g.DrawImage(EEGraphics.fieldFortification, actualPointToDrawAt);
        }

        public static void PaintHeavyFieldFortification(Graphics g, Point ptToDrawAt)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= EEGraphics.heavyFieldFortification.Width / 2;
            actualPointToDrawAt.Y -= EEGraphics.heavyFieldFortification.Height / 2;

            g.DrawImage(EEGraphics.heavyFieldFortification, actualPointToDrawAt);
        }

        public static void PaintHeavyFieldFortification(Graphics g, Rectangle recToDrawOn)
        {
            g.DrawImage(EEGraphics.heavyFieldFortification, recToDrawOn);
        }

        public static void PaintAxisMinorStepMarker(Graphics g, Point ptToDrawAt)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= EEGraphics.fieldFortification.Width / 2;
            actualPointToDrawAt.Y -= EEGraphics.fieldFortification.Height / 2;

            g.DrawImage(EEGraphics.axisMinorStep, actualPointToDrawAt);
        }

        public static void PaintAxisBeachHead(Graphics g, Point ptToDrawAt)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= EEGraphics.axisBeachhead.Width / 2;
            actualPointToDrawAt.Y -= EEGraphics.axisBeachhead.Height / 2;

            g.DrawImage(EEGraphics.axisBeachhead, actualPointToDrawAt);
        }

        public static void PaintSovietBeachHead(Graphics g, Point ptToDrawAt)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= EEGraphics.sovietBeachHead.Width / 2;
            actualPointToDrawAt.Y -= EEGraphics.sovietBeachHead.Height / 2;

            g.DrawImage(EEGraphics.sovietBeachHead, actualPointToDrawAt);
        }

        public static void PaintWAlliesBeachHead(Graphics g, Point ptToDrawAt)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= EEGraphics.wAlliedBeachHead.Width / 2;
            actualPointToDrawAt.Y -= EEGraphics.wAlliedBeachHead.Height / 2;

            g.DrawImage(EEGraphics.wAlliedBeachHead, actualPointToDrawAt);
        }

        public static void PaintHitDie(Graphics g, Point ptToDrawAt,int dieNum, bool hit)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= GetDieSize().Width / 2;
            actualPointToDrawAt.Y -= GetDieSize().Height / 2;
            if(hit)
            {
                switch(dieNum)
                {
                    case 1:
                        g.DrawImage(EEGraphics.oneSidedDiceRed, actualPointToDrawAt);
                        break;
                    case 2:
                        g.DrawImage(EEGraphics.twoSidedDiceRed, actualPointToDrawAt);
                        break;
                    case 3:
                        g.DrawImage(EEGraphics.threeSidedDiceRed, actualPointToDrawAt);
                        break;
                    case 4:
                        g.DrawImage(EEGraphics.fourSidedDiceRed, actualPointToDrawAt);
                        break;
                    case 5:
                        g.DrawImage(EEGraphics.fiveSidedDiceRed, actualPointToDrawAt);
                        break;
                    case 6:
                        g.DrawImage(EEGraphics.sixSidedDiceRed, actualPointToDrawAt);
                        break;
                    default:
                        throw new InvalidOperationException("Invalid die number specified");
                }
            }
            else
            {
                switch (dieNum)
                {
                    case 1:
                        g.DrawImage(EEGraphics.oneSidedDiceWhite, actualPointToDrawAt);
                        break;
                    case 2:
                        g.DrawImage(EEGraphics.twoSidedDiceWhite, actualPointToDrawAt);
                        break;
                    case 3:
                        g.DrawImage(EEGraphics.threeSidedDiceWhite, actualPointToDrawAt);
                        break;
                    case 4:
                        g.DrawImage(EEGraphics.fourSidedDiceWhite, actualPointToDrawAt);
                        break;
                    case 5:
                        g.DrawImage(EEGraphics.fiveSidedDiceWhite, actualPointToDrawAt);
                        break;
                    case 6:
                        g.DrawImage(EEGraphics.sixSidedDiceWhite, actualPointToDrawAt);
                        break;
                    default:
                        throw new InvalidOperationException("Invalid die number specified");
                }
            }
        }

        public static void PaintMiniGSU(Graphics g, MapInfo.CountryID country, Point ptToDrawAt)
        {
            Point actualPointToDrawAt = ptToDrawAt;
            actualPointToDrawAt.X -= EEGraphics.BritishGSUMini.Width / 2;
            actualPointToDrawAt.Y -= EEGraphics.BritishGSUMini.Height / 2;
            switch(country)
            {
                case MapInfo.CountryID.GreatBritain:
                    g.DrawImage(EEGraphics.BritishGSUMini, actualPointToDrawAt);
                    break;
                case MapInfo.CountryID.France:
                    g.DrawImage(EEGraphics.FrenchGSUMini, actualPointToDrawAt);
                    break;
                case MapInfo.CountryID.Germany:
                    g.DrawImage(EEGraphics.GermanGSUMini, actualPointToDrawAt);
                    break;
                case MapInfo.CountryID.Italy:
                    g.DrawImage(EEGraphics.ItaGSUMini, actualPointToDrawAt);
                    break;
                case MapInfo.CountryID.USSR:
                    g.DrawImage(EEGraphics.SovietGSUMini, actualPointToDrawAt);
                    break;
                case MapInfo.CountryID.USA:
                    g.DrawImage(EEGraphics.USGSUMini, actualPointToDrawAt);
                    break;
                default:
                    throw new ArgumentException("Invalid Country For Mini GSU");
            }
        }

        public static System.Windows.Forms.ImageList GetPlayingPieceImageList(List<PlayingPiece> listOfPlayingPieces)
        {
            System.Windows.Forms.ImageList playingPieceImageList = new System.Windows.Forms.ImageList();
            playingPieceImageList.ImageSize = GetBlockSize();
            foreach(PlayingPiece playingPiece in listOfPlayingPieces)
            {
                if(playingPiece is Block)
                {
                    playingPieceImageList.Images.Add(GetBlockImage((Block)playingPiece));
                }
                else if (playingPiece is GroundSupportUnit)
                {
                    playingPieceImageList.Images.Add(GetGSUImage((GroundSupportUnit)playingPiece, false));
                }
            }

            return playingPieceImageList;
        }

        public static void PaintArrow(Graphics g, PointF startPoint, PointF endPoint, Color lineColor, bool filled, bool showLabel)
        {
            try
            {
                g.DrawLine(new Pen(lineColor, 3F), startPoint, endPoint);

                SolidBrush brush = new SolidBrush(lineColor);
                double angle = Math.Atan2(endPoint.Y - startPoint.Y, endPoint.X - startPoint.X);
                double length = Math.Sqrt((endPoint.X - startPoint.X) * (endPoint.X - startPoint.X) + (endPoint.Y - startPoint.Y) * (endPoint.Y - startPoint.Y)) - 10;
                double delta = Math.Atan2(7, length);
                PointF left = new PointF(Convert.ToSingle(startPoint.X + length * Math.Cos(angle - delta)), Convert.ToSingle(startPoint.Y + length * Math.Sin(angle - delta)));
                PointF right = new PointF(Convert.ToSingle(startPoint.X + length * Math.Cos(angle + delta)), Convert.ToSingle(startPoint.Y + length * Math.Sin(angle + delta)));

                PointF[] points ={ left, endPoint, right };
                if (filled)
                    g.FillPolygon(brush, points);
                else
                {
                    Pen p = new Pen(brush, 1F);
                    g.DrawLines(p, points);
                }
                if (showLabel)
                {
                    g.DrawString("(" + endPoint.X + "," + endPoint.Y + ")", new Font("Arial", 10), brush, new PointF(endPoint.X - 20, endPoint.Y - 20));
                }
            }
            catch (Exception)
            {

            }
        }

        public static Size GetFleetSize()
        {
            return EEGraphics.SovietFleetPoint.Size;
        }

        public static Size GetBlockSize()
        {
            return EEGraphics.French2StepArmor.Size;
        }

        public static Size GetBlockBackingSize()
        {
            return EEGraphics.FrenchBlockBacking.Size;
        }

        public static Size GetGSUSize()
        {
            return EEGraphics.FrenchGSUDogfight.Size;
        }

        public static Size GetMiniTransparentSASize()
        {
            return EEGraphics.MiniTransparentFrenchControlSAs.Size;
        }

        public static Size GetSASize()
        {
            return EEGraphics.FrenchControlSAs.Size;
        }

        public static Size GetMarkerSize()
        {
            return EEGraphics.FrenchFleetPoint.Size;
        }

        public static Size GetDieSize()
        {
            return EEGraphics.oneSidedDiceRed.Size;
        }
    }
}
